package com.media.selector.media.adapter

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.media.selector.R
import com.media.selector.databinding.ItemMediaItemBinding
import com.media.selector.media.listener.OnMediaItemClickListener
import com.media.selector.media.listener.OnMediaViewClickListener
import com.media.selector.media.model.SelectedCollection
import com.media.selector.media.model.SelectionSpec
import com.media.selector.media.model.entity.MediaEntity
import com.media.selector.widget.MediaGridView
import java.util.*

/**
 * date        ：2020/4/27
 * author      ：蒙景博
 * description ：
 */
class MediaItemAdapter constructor(private val selectedCollection: SelectedCollection): RecyclerView.Adapter<RecyclerView.ViewHolder>(), OnMediaViewClickListener {

    companion object {
        private const val VIEW_TYPE_CAPTURE = 0x01
        private const val VIEW_TYPE_MEDIA = 0x02
    }

    private var mOnMediaItemClickListener: OnMediaItemClickListener? = null

    // 异步更新列表
    private val mAsyncListChange by lazy { AsyncListDiffer(this, DiffItemCallback()) }

    init {
        setHasStableIds(true)
    }

    fun notifyAdapterChanged(source: List<MediaEntity>) {
        this.mAsyncListChange.submitList(Collections.unmodifiableList(source))
    }

    fun setOnMediaItemClickListener(listener: OnMediaItemClickListener) {
        this.mOnMediaItemClickListener = listener
    }

    override fun getItemCount(): Int = mAsyncListChange.currentList.size

    override fun getItemViewType(position: Int): Int {
        return if(mAsyncListChange.currentList[position].isCapture()) VIEW_TYPE_CAPTURE else VIEW_TYPE_MEDIA
    }

    override fun getItemId(position: Int): Long = position.toLong()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return if (viewType == VIEW_TYPE_CAPTURE) {
            CameraViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_camera_item, parent, false))
        } else {
            MediaViewHolder(DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.item_media_item, parent, false))
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        if (holder is CameraViewHolder) {
            holder.itemView.setOnClickListener { mOnMediaItemClickListener?.onTakePhoto() }
        } else if (holder is MediaViewHolder){
            val mMedia = mAsyncListChange.currentList[position]
            holder.binding.mediaContainer.tag = mMedia
            holder.binding.mediaContainer
                .setMediaData(this, position, mMedia)
                .setChecked(selectedCollection.isSelected(mMedia))
        }
    }

    override fun onThumbnailClicked(position: Int, media: MediaEntity) {
        val mPosition = if (SelectionSpec.with().capture) position - 1 else position
        mOnMediaItemClickListener?.onMediaClick(false, mPosition)
    }

    override fun onCheckViewClicked(position: Int, media: MediaEntity) {
        if (selectedCollection.isSelected(media)) {
            selectedCollection.removeMedia(media)
            notifyDataSetChanged(position)
        } else {
            if (selectedCollection.checkSelectedMedia(media)) {
                selectedCollection.addMedia(media)
                notifyDataSetChanged(position)
            }
        }
    }

    private fun notifyDataSetChanged(position: Int) {
        if (position != MediaGridView.UNKNOWN_POSITION) {
            notifyItemChanged(position)
        } else {
            notifyDataSetChanged()
        }
        mOnMediaItemClickListener?.onCheckedStateChanged()
    }

    private inner class CameraViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {

        init {
            // 如果存在相机入口时，这里设置相机 Item 大小，防止无内容时，相机 Item 变形
            val mCameraSize = itemView.resources.displayMetrics.widthPixels / 4
            val mParams = itemView.layoutParams
            mParams.height = mCameraSize
            itemView.layoutParams = mParams
        }
    }

    private inner class MediaViewHolder constructor(val binding: ItemMediaItemBinding): RecyclerView.ViewHolder(binding.root)

    private class DiffItemCallback : DiffUtil.ItemCallback<MediaEntity>(){
        override fun areItemsTheSame(oldItem: MediaEntity, newItem: MediaEntity) = oldItem.hashCode() == newItem.hashCode()
        override fun areContentsTheSame(oldItem: MediaEntity, newItem: MediaEntity) = oldItem.id == newItem.id && oldItem.mimeType == newItem.mimeType && oldItem.contentUri == newItem.contentUri && oldItem.size == newItem.size && oldItem.duration == newItem.duration
    }
}